package com.gupao.vip.mic.zkclient;

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkNodeExistsException;

public class MasterSelector {

	private static final String MASTER_PATH="/server";
	
	private UserCenter slave;
	
	private UserCenter master;
	
	private ZkClient  zkClient;
	
	private IZkDataListener dataListener;
	
	private Boolean isRunning=false;
	
	private ScheduledExecutorService  scheduledExecutorService;
	
	public MasterSelector(UserCenter slave,ZkClient  zkClient){
		this.zkClient=zkClient;
		this.slave=slave;
		
		dataListener=new IZkDataListener() {
			public void handleDataDeleted(String arg0) throws Exception {
				
			}
			public void handleDataChange(String arg0, Object arg1) throws Exception {
				//如果节点被删除，发起选举操作
				chooseMaster();
			}
		};
	}
	
	/**
	 * start 方法的内容
	 * 1 设置isRunning为true
	 * 2 添加监控
	 * 3 执行选举
	 */
	public void start(){
		if(!isRunning){
			isRunning=true;
			zkClient.subscribeDataChanges(MASTER_PATH, dataListener);
			chooseMaster();
		}
	}
	
	/**
	 * stop 方法的内容
	 * 1 设置isRunning为false
	 * 2 关闭定时调度
	 * 3 取消订阅监控
	 * 4 释放锁，即删除master
	 */
	public void stop(){
		if(isRunning){
			isRunning=false;
			scheduledExecutorService.shutdown();
			zkClient.unsubscribeDataChanges(MASTER_PATH, dataListener);
			releaseMaster();
		}
	}
	
	/**
	 * 选举主节点的方法：
	 * 1  判断当前服务是否启动
	 * 2 创建主节点，把当前从节点的值赋值给主节点
	 * 3 定时器执行每固定5秒钟释放锁(重要)
	 * 4 异常捕获创建主节点(当前节点已经存在)，再次读取主节点，
	 *    如果为空，执行选举方法
	 *    如果不为空 将读取到的当前节点赋值给主节点
	 */
	private void chooseMaster(){
		if(!isRunning){
			System.out.println("当前服务没有启动");
			return ;
		}
		try {
			zkClient.createEphemeral(MASTER_PATH, slave);
			master=slave;
			System.out.println(master+"->我现在已经是master，你们要听我的");
		
			scheduledExecutorService.schedule(new Runnable() {
				public void run() {
					releaseMaster();
				}
			}, 2, TimeUnit.SECONDS);
		} catch (ZkNodeExistsException e) {
			UserCenter userCenter=zkClient.readData(MASTER_PATH);
			if(userCenter==null){
				System.out.println("启动操作");
				//释放锁
				releaseMaster();
			}else{
				master=userCenter;
			}
		}
		
	
	}
	
	//释放锁
	private void releaseMaster(){
		/**
		 * 1 判断当前的server是不是master 只有master才需要释放锁
		 * 2 执行删除操作
		 */
		if(checkIsMaster()){
			zkClient.delete(MASTER_PATH);
		}
	}
	
	//判断当前的server是不是master
	public  boolean checkIsMaster(){
		/**
		 * 1  得到主服务器
		 * 2  判断当前服务器是否是主服务器
		 */
		UserCenter userCenter=zkClient.readData(MASTER_PATH);
		if(userCenter.getMc_name().equals(master.getMc_name())){
			return true;
		}
		return false;
	}
}
